#include <iostream>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <string>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include "signIn.hpp"

void* chat_server(void* ptr)
{
	signIn *si = reinterpret_cast<signIn *>(ptr);
	int portno = 6565;
	int new_sockfd;
	void *retval = NULL;
	int serverfd = ::socket(AF_INET, SOCK_STREAM, 0);
	if (serverfd < 0) {
		std::cerr << "ERROR opening socket" << std::endl;
		return retval;
	}
	sockaddr_in serv_addr;
	memset(&serv_addr, 0, sizeof(sockaddr_in));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);
	if(bind(serverfd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
		std::cerr << "Can't bind socket: errno " << errno << std::endl;
		return retval;
	}
	listen(serverfd, 10);
	sockaddr_in cli_addr;
	socklen_t cli_len = sizeof(cli_addr);
	std::cout << "chatting server run successfully " << std::endl;
	while(true){
		new_sockfd = ::accept(serverfd, (sockaddr*)&cli_addr, &cli_len);
		char* host_name = inet_ntoa(cli_addr.sin_addr);
		std::cout << "Conenction from " << host_name << std::endl; 
		si->w->fd = new_sockfd;
		si->w->h = host_name;

		char buff[255];
		int n = ::read(new_sockfd, buff, 255);
		if(n < 0)
			std::cout << "Error reading from socket\n";
		si->w->remoteNick = buff;

		int ln = (si->w->hostNick.toStdString()).length() + 1;
		char *host_nick_name = new char [ln];

		strcpy(host_nick_name,
				(char*)(si->w->hostNick.toStdString().c_str()));
		host_nick_name[ln-1] = '\0';
		n = ::write(new_sockfd, host_nick_name, ln);
		if(n < 0)
			std::cout << "Error reading from socket\n";
		si->w->eConnections();
	}
	return retval;
}
